#include "Buffer.h"
#include "System.h"
#include <new>
#include <memory.h>


namespace illib{
	namespace Buffer{
		Static::Static(uint8_t * data, size_t size) :
			Memory(data, size)
		{

		}
		Static::~Static()
		{
		}


		Static::Static(Allocator &allocator, size_t size) :
			Memory(0,0)
		{
			size_t allocated;
			block_ = allocator.allocate(size, allocated);
			blockSize_ = size;
		}
		void Static::setup(Allocator &allocator, size_t size)
		{
			size_t allocated;
			block_ = allocator.allocate(size, allocated);
			blockSize_ = size;
		}
		void Static::setup(uint8_t * data, size_t size)
		{
			block_ = data;
			blockSize_ = size;
		}
		void Static::destroy(){
			assert(MemoryTracker::tracker().release(start()));
			this->~Static();
		}
		size_t Static::allocated(){
			MemoryTracker::Tracked * entry = MemoryTracker::tracker().entry(block_);
			if(!entry) return blockSize_;
			return entry->size();
		}
		bool Static::tracked(){
			MemoryTracker::Tracked * entry = MemoryTracker::tracker().entry(block_);
			if(!entry) return false;
			if(!entry->allocator()) return false;
			return true;
		}
		bool Static::resize(size_t size, bool keep){
			MemoryTracker::Tracked * entry = MemoryTracker::tracker().entry(block_);
			if (!entry) return false;
			if (size < allocated()){
				blockSize_ = size;
				return true;
			}
			assert(entry->allocator());
			Allocator * root = entry->allocator()->root();
			assert(root);
			size_t allocated;
			uint8_t * memory = root->allocate(size, allocated);
			if(keep){
				memcpy(memory, block_, blockSize_);
			}
			MemoryTracker::tracker().release(block_);
			block_ = memory;
			blockSize_ = size;
			return true;
		}
	}
}
